home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-10-28 | 61.3 KB | 1,519 lines |
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- NNNNAAAAMMMMEEEE
- perlfaq8 - System Interaction ($Revision: 1.26 $, $Date:
- 1998/08/05 12:20:28 $)
-
- DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
- This section of the Perl FAQ covers questions involving
- operating system interaction. This involves interprocess
- communication (IPC), control over the user-interface
- (keyboard, screen and pointing devices), and most anything
- else not related to data manipulation.
-
- Read the FAQs and documentation specific to the port of perl
- to your operating system (eg, the _p_e_r_l_v_m_s manpage, the
- _p_e_r_l_p_l_a_n_9 manpage, ...). These should contain more detailed
- information on the vagaries of your perl.
-
- HHHHoooowwww ddddoooo IIII ffffiiiinnnndddd oooouuuutttt wwwwhhhhiiiicccchhhh ooooppppeeeerrrraaaattttiiiinnnngggg ssssyyyysssstttteeeemmmm IIII''''mmmm rrrruuuunnnnnnnniiiinnnngggg uuuunnnnddddeeeerrrr????
-
- The $^O variable ($OSNAME if you use English) contains the
- operating system that your perl binary was built for.
-
- HHHHoooowwww ccccoooommmmeeee _e_x_e_c() doesn't return?
-
- Because that's what it does: it replaces your currently
- running program with a different one. If you want to keep
- going (as is probably the case if you're asking this
- question) use _s_y_s_t_e_m() instead.
-
- HHHHoooowwww ddddoooo IIII ddddoooo ffffaaaannnnccccyyyy ssssttttuuuuffffffff wwwwiiiitttthhhh tttthhhheeee kkkkeeeeyyyybbbbooooaaaarrrrdddd////ssssccccrrrreeeeeeeennnn////mmmmoooouuuusssseeee????
-
- How you access/control keyboards, screens, and pointing
- devices ("mice") is system-dependent. Try the following
- modules:
-
- Keyboard
-
- Term::Cap Standard perl distribution
- Term::ReadKey CPAN
- Term::ReadLine::Gnu CPAN
- Term::ReadLine::Perl CPAN
- Term::Screen CPAN
-
-
- Screen
-
- Term::Cap Standard perl distribution
- Curses CPAN
- Term::ANSIColor CPAN
-
-
- Mouse
-
-
-
-
- Page 1 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- Tk CPAN
-
-
- Some of these specific cases are shown below.
-
- HHHHoooowwww ddddoooo IIII pppprrrriiiinnnntttt ssssoooommmmeeeetttthhhhiiiinnnngggg oooouuuutttt iiiinnnn ccccoooolllloooorrrr????
-
- In general, you don't, because you don't know whether the
- recipient has a color-aware display device. If you know
- that they have an ANSI terminal that understands color, you
- can use the Term::ANSIColor module from CPAN:
-
- use Term::ANSIColor;
- print color("red"), "Stop!\n", color("reset");
- print color("green"), "Go!\n", color("reset");
-
- Or like this:
-
- use Term::ANSIColor qw(:constants);
- print RED, "Stop!\n", RESET;
- print GREEN, "Go!\n", RESET;
-
-
- HHHHoooowwww ddddoooo IIII rrrreeeeaaaadddd jjjjuuuusssstttt oooonnnneeee kkkkeeeeyyyy wwwwiiiitttthhhhoooouuuutttt wwwwaaaaiiiittttiiiinnnngggg ffffoooorrrr aaaa rrrreeeettttuuuurrrrnnnn kkkkeeeeyyyy????
-
- Controlling input buffering is a remarkably system-dependent
- matter. If most systems, you can just use the ssssttttttttyyyy command
- as shown in the getc entry in the _p_e_r_l_f_u_n_c manpage, but as
- you see, that's already getting you into portability snags.
-
- open(TTY, "+</dev/tty") or die "no tty: $!";
- system "stty cbreak </dev/tty >/dev/tty 2>&1";
- $key = getc(TTY); # perhaps this works
- # OR ELSE
- sysread(TTY, $key, 1); # probably this does
- system "stty -cbreak </dev/tty >/dev/tty 2>&1";
-
- The Term::ReadKey module from CPAN offers an easy-to-use
- interface that should be more efficient than shelling out to
- ssssttttttttyyyy for each key. It even includes limited support for
- Windows.
-
- use Term::ReadKey;
- ReadMode('cbreak');
- $key = ReadKey(0);
- ReadMode('normal');
-
- However, that requires that you have a working C compiler
- and can use it to build and install a CPAN module. Here's a
- solution using the standard POSIX module, which is already
- on your systems (assuming your system supports POSIX).
-
-
-
-
- Page 2 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- use HotKey;
- $key = readkey();
-
- And here's the HotKey module, which hides the somewhat
- mystifying calls to manipulate the POSIX termios structures.
-
- # HotKey.pm
- package HotKey;
-
- @ISA = qw(Exporter);
- @EXPORT = qw(cbreak cooked readkey);
-
- use strict;
- use POSIX qw(:termios_h);
- my ($term, $oterm, $echo, $noecho, $fd_stdin);
-
- $fd_stdin = fileno(STDIN);
- $term = POSIX::Termios->new();
- $term->getattr($fd_stdin);
- $oterm = $term->getlflag();
-
- $echo = ECHO | ECHOK | ICANON;
- $noecho = $oterm & ~$echo;
-
- sub cbreak {
- $term->setlflag($noecho); # ok, so i don't want echo either
- $term->setcc(VTIME, 1);
- $term->setattr($fd_stdin, TCSANOW);
- }
-
- sub cooked {
- $term->setlflag($oterm);
- $term->setcc(VTIME, 0);
- $term->setattr($fd_stdin, TCSANOW);
- }
-
- sub readkey {
- my $key = '';
- cbreak();
- sysread(STDIN, $key, 1);
- cooked();
- return $key;
- }
-
- END { cooked() }
-
- 1;
-
-
-
-
-
-
-
-
- Page 3 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- HHHHoooowwww ddddoooo IIII cccchhhheeeecccckkkk wwwwhhhheeeetttthhhheeeerrrr iiiinnnnppppuuuutttt iiiissss rrrreeeeaaaaddddyyyy oooonnnn tttthhhheeee kkkkeeeeyyyybbbbooooaaaarrrrdddd????
-
- The easiest way to do this is to read a key in nonblocking
- mode with the Term::ReadKey module from CPAN, passing it an
- argument of -1 to indicate not to block:
-
- use Term::ReadKey;
-
- ReadMode('cbreak');
-
- if (defined ($char = ReadKey(-1)) ) {
- # input was waiting and it was $char
- } else {
- # no input was waiting
- }
-
- ReadMode('normal'); # restore normal tty settings
-
-
- HHHHoooowwww ddddoooo IIII cccclllleeeeaaaarrrr tttthhhheeee ssssccccrrrreeeeeeeennnn????
-
- If you only have to so infrequently, use system:
-
- system("clear");
-
- If you have to do this a lot, save the clear string so you
- can print it 100 times without calling a program 100 times:
-
- $clear_string = `clear`;
- print $clear_string;
-
- If you're planning on doing other screen manipulations, like
- cursor positions, etc, you might wish to use Term::Cap
- module:
-
- use Term::Cap;
- $terminal = Term::Cap->Tgetent( {OSPEED => 9600} );
- $clear_string = $terminal->Tputs('cl');
-
-
- HHHHoooowwww ddddoooo IIII ggggeeeetttt tttthhhheeee ssssccccrrrreeeeeeeennnn ssssiiiizzzzeeee????
-
- If you have Term::ReadKey module installed from CPAN, you
- can use it to fetch the width and height in characters and
- in pixels:
-
- use Term::ReadKey;
- ($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize();
-
- This is more portable than the raw ioctl, but not as
- illustrative:
-
-
-
-
- Page 4 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- require 'sys/ioctl.ph';
- die "no TIOCGWINSZ " unless defined &TIOCGWINSZ;
- open(TTY, "+</dev/tty") or die "No tty: $!";
- unless (ioctl(TTY, &TIOCGWINSZ, $winsize='')) {
- die sprintf "$0: ioctl TIOCGWINSZ (%08x: $!)\n", &TIOCGWINSZ;
- }
- ($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize);
- print "(row,col) = ($row,$col)";
- print " (xpixel,ypixel) = ($xpixel,$ypixel)" if $xpixel || $ypixel;
- print "\n";
-
-
- HHHHoooowwww ddddoooo IIII aaaasssskkkk tttthhhheeee uuuusssseeeerrrr ffffoooorrrr aaaa ppppaaaasssssssswwwwoooorrrrdddd????
-
- (This question has nothing to do with the web. See a
- different FAQ for that.)
-
- There's an example of this in the crypt entry in the
- _p_e_r_l_f_u_n_c manpage). First, you put the terminal into "no
- echo" mode, then just read the password normally. You may
- do this with an old-style _i_o_c_t_l() function, POSIX terminal
- control (see the _P_O_S_I_X manpage, and Chapter 7 of the Camel),
- or a call to the ssssttttttttyyyy program, with varying degrees of
- portability.
-
- You can also do this for most systems using the
- Term::ReadKey module from CPAN, which is easier to use and
- in theory more portable.
-
- use Term::ReadKey;
-
- ReadMode('noecho');
- $password = ReadLine(0);
-
-
- HHHHoooowwww ddddoooo IIII rrrreeeeaaaadddd aaaannnndddd wwwwrrrriiiitttteeee tttthhhheeee sssseeeerrrriiiiaaaallll ppppoooorrrrtttt????
-
- This depends on which operating system your program is
- running on. In the case of Unix, the serial ports will be
- accessible through files in /dev; on other systems, the
- devices names will doubtless differ. Several problem areas
- common to all device interaction are the following
-
- lockfiles
- Your system may use lockfiles to control multiple
- access. Make sure you follow the correct protocol.
- Unpredictable behaviour can result from multiple
- processes reading from one device.
-
- open mode
- If you expect to use both read and write operations on
- the device, you'll have to open it for update (see the
-
-
-
- Page 5 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- section on _o_p_e_n in the _p_e_r_l_f_u_n_c manpage for details).
- You may wish to open it without running the risk of
- blocking by using _s_y_s_o_p_e_n() and O_RDWR|O_NDELAY|O_NOCTTY
- from the Fcntl module (part of the standard perl
- distribution). See the section on _s_y_s_o_p_e_n in the
- _p_e_r_l_f_u_n_c manpage for more on this approach.
-
- end of line
- Some devices will be expecting a "\r" at the end of each
- line rather than a "\n". In some ports of perl, "\r"
- and "\n" are different from their usual (Unix) ASCII
- values of "\012" and "\015". You may have to give the
- numeric values you want directly, using octal ("\015"),
- hex ("0x0D"), or as a control-character specification
- ("\cM").
-
- print DEV "atv1\012"; # wrong, for some devices
- print DEV "atv1\015"; # right, for some devices
-
- Even though with normal text files, a "\n" will do the
- trick, there is still no unified scheme for terminating
- a line that is portable between Unix, DOS/Win, and
- Macintosh, except to terminate _A_L_L line ends with
- "\015\012", and strip what you don't need from the
- output. This applies especially to socket I/O and
- autoflushing, discussed next.
-
- flushing output
- If you expect characters to get to your device when you
- _p_r_i_n_t() them, you'll want to autoflush that filehandle.
- You can use _s_e_l_e_c_t() and the $| variable to control
- autoflushing (see the section on $| in the _p_e_r_l_v_a_r
- manpage and the select entry in the _p_e_r_l_f_u_n_c manpage):
-
- $oldh = select(DEV);
- $| = 1;
- select($oldh);
-
- You'll also see code that does this without a temporary
- variable, as in
-
- select((select(DEV), $| = 1)[0]);
-
- Or if you don't mind pulling in a few thousand lines of
- code just because you're afraid of a little $| variable:
-
- use IO::Handle;
- DEV->autoflush(1);
-
- As mentioned in the previous item, this still doesn't
- work when using socket I/O between Unix and Macintosh.
- You'll need to hardcode your line terminators, in that
-
-
-
- Page 6 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- case.
-
- non-blocking input
- If you are doing a blocking _r_e_a_d() or _s_y_s_r_e_a_d(), you'll
- have to arrange for an alarm handler to provide a
- timeout (see the alarm entry in the _p_e_r_l_f_u_n_c manpage).
- If you have a non-blocking open, you'll likely have a
- non-blocking read, which means you may have to use a 4-
- arg _s_e_l_e_c_t() to determine whether I/O is ready on that
- device (see the section on _s_e_l_e_c_t in the _p_e_r_l_f_u_n_c
- manpage.
-
- While trying to read from his caller-id box, the notorious
- Jamie Zawinski <jwz@netscape.com>, after much gnashing of
- teeth and fighting with sysread, sysopen, POSIX's tcgetattr
- business, and various other functions that go bump in the
- night, finally came up with this:
-
- sub open_modem {
- use IPC::Open2;
- my $stty = `/bin/stty -g`;
- open2( \*MODEM_IN, \*MODEM_OUT, "cu -l$modem_device -s2400 2>&1");
- # starting cu hoses /dev/tty's stty settings, even when it has
- # been opened on a pipe...
- system("/bin/stty $stty");
- $_ = <MODEM_IN>;
- chop;
- if ( !m/^Connected/ ) {
- print STDERR "$0: cu printed `$_' instead of `Connected'\n";
- }
- }
-
-
- HHHHoooowwww ddddoooo IIII ddddeeeeccccooooddddeeee eeeennnnccccrrrryyyypppptttteeeedddd ppppaaaasssssssswwwwoooorrrrdddd ffffiiiilllleeeessss????
-
- You spend lots and lots of money on dedicated hardware, but
- this is bound to get you talked about.
-
- Seriously, you can't if they are Unix password files - the
- Unix password system employs one-way encryption. It's more
- like hashing than encryption. The best you can check is
- whether something else hashes to the same string. You can't
- turn a hash back into the original string. Programs like
- Crack can forcibly (and intelligently) try to guess
- passwords, but don't (can't) guarantee quick success.
-
- If you're worried about users selecting bad passwords, you
- should proactively check when they try to change their
- password (by modifying _p_a_s_s_w_d(1), for example).
-
-
-
-
-
-
- Page 7 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- HHHHoooowwww ddddoooo IIII ssssttttaaaarrrrtttt aaaa pppprrrroooocccceeeessssssss iiiinnnn tttthhhheeee bbbbaaaacccckkkkggggrrrroooouuuunnnndddd????
-
- You could use
-
- system("cmd &")
-
- or you could use fork as documented in the section on _f_o_r_k
- in the _p_e_r_l_f_u_n_c manpage, with further examples in the
- _p_e_r_l_i_p_c manpage. Some things to be aware of, if you're on a
- Unix-like system:
-
- STDIN, STDOUT, and STDERR are shared
- Both the main process and the backgrounded one (the
- "child" process) share the same STDIN, STDOUT and STDERR
- filehandles. If both try to access them at once,
- strange things can happen. You may want to close or
- reopen these for the child. You can get around this
- with opening a pipe (see the section on _o_p_e_n in the
- _p_e_r_l_f_u_n_c manpage) but on some systems this means that
- the child process cannot outlive the parent.
-
- Signals
- You'll have to catch the SIGCHLD signal, and possibly
- SIGPIPE too. SIGCHLD is sent when the backgrounded
- process finishes. SIGPIPE is sent when you write to a
- filehandle whose child process has closed (an untrapped
- SIGPIPE can cause your program to silently die). This
- is not an issue with system("cmd&").
-
- Zombies
- You have to be prepared to "reap" the child process when
- it finishes
-
- $SIG{CHLD} = sub { wait };
-
- See the section on _S_i_g_n_a_l_s in the _p_e_r_l_i_p_c manpage for
- other examples of code to do this. Zombies are not an
- issue with system("prog &").
-
- HHHHoooowwww ddddoooo IIII ttttrrrraaaapppp ccccoooonnnnttttrrrroooollll cccchhhhaaaarrrraaaacccctttteeeerrrrssss////ssssiiiiggggnnnnaaaallllssss????
-
- You don't actually "trap" a control character. Instead,
- that character generates a signal which is sent to your
- terminal's currently foregrounded process group, which you
- then trap in your process. Signals are documented in the
- section on _S_i_g_n_a_l_s in the _p_e_r_l_i_p_c manpage and chapter 6 of
- the Camel.
-
- Be warned that very few C libraries are re-entrant.
- Therefore, if you attempt to _p_r_i_n_t() in a handler that got
- invoked during another stdio operation your internal
- structures will likely be in an inconsistent state, and your
-
-
-
- Page 8 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- program will dump core. You can sometimes avoid this by
- using _s_y_s_w_r_i_t_e() instead of _p_r_i_n_t().
-
- Unless you're exceedingly careful, the only safe things to
- do inside a signal handler are: set a variable and exit.
- And in the first case, you should only set a variable in
- such a way that _m_a_l_l_o_c() is not called (eg, by setting a
- variable that already has a value).
-
- For example:
-
- $Interrupted = 0; # to ensure it has a value
- $SIG{INT} = sub {
- $Interrupted++;
- syswrite(STDERR, "ouch\n", 5);
- }
-
- However, because syscalls restart by default, you'll find
- that if you're in a "slow" call, such as <FH>, _r_e_a_d(),
- _c_o_n_n_e_c_t(), or _w_a_i_t(), that the only way to terminate them is
- by "longjumping" out; that is, by raising an exception. See
- the time-out handler for a blocking _f_l_o_c_k() in the section
- on _S_i_g_n_a_l_s in the _p_e_r_l_i_p_c manpage or chapter 6 of the Camel.
-
- HHHHoooowwww ddddoooo IIII mmmmooooddddiiiiffffyyyy tttthhhheeee sssshhhhaaaaddddoooowwww ppppaaaasssssssswwwwoooorrrrdddd ffffiiiilllleeee oooonnnn aaaa UUUUnnnniiiixxxx ssssyyyysssstttteeeemmmm????
-
- If perl was installed correctly, and your shadow library was
- written properly, the getpw*() functions described in the
- _p_e_r_l_f_u_n_c manpage should in theory provide (read-only) access
- to entries in the shadow password file. To change the file,
- make a new shadow password file (the format varies from
- system to system - see the _p_a_s_s_w_d(_5) manpage for specifics)
- and use _p_w_d__m_k_d_b(8) to install it (see the _p_w_d__m_k_d_b(_5)
- manpage for more details).
-
- HHHHoooowwww ddddoooo IIII sssseeeetttt tttthhhheeee ttttiiiimmmmeeee aaaannnndddd ddddaaaatttteeee????
-
- Assuming you're running under sufficient permissions, you
- should be able to set the system-wide date and time by
- running the _d_a_t_e(1) program. (There is no way to set the
- time and date on a per-process basis.) This mechanism will
- work for Unix, MS-DOS, Windows, and NT; the VMS equivalent
- is set time.
-
- However, if all you want to do is change your timezone, you
- can probably get away with setting an environment variable:
-
- $ENV{TZ} = "MST7MDT"; # unixish
- $ENV{'SYS$TIMEZONE_DIFFERENTIAL'}="-5" # vms
- system "trn comp.lang.perl.misc";
-
-
-
-
-
- Page 9 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- HHHHoooowwww ccccaaaannnn IIII _s_l_e_e_p() or _a_l_a_r_m() for under a second?
-
- If you want finer granularity than the 1 second that the
- _s_l_e_e_p() function provides, the easiest way is to use the
- _s_e_l_e_c_t() function as documented in the section on _s_e_l_e_c_t in
- the _p_e_r_l_f_u_n_c manpage. If your system has itimers and
- _s_y_s_c_a_l_l() support, you can check out the old example in
- http://www.perl.com/CPAN/doc/misc/ancient/tutorial/eg/itimers.pl
- .
-
- HHHHoooowwww ccccaaaannnn IIII mmmmeeeeaaaassssuuuurrrreeee ttttiiiimmmmeeee uuuunnnnddddeeeerrrr aaaa sssseeeeccccoooonnnndddd????
-
- In general, you may not be able to. The Time::HiRes module
- (available from CPAN) provides this functionality for some
- systems.
-
- In general, you may not be able to. But if your system
- supports both the _s_y_s_c_a_l_l() function in Perl as well as a
- system call like _g_e_t_t_i_m_e_o_f_d_a_y(2), then you may be able to do
- something like this:
-
- require 'sys/syscall.ph';
-
- $TIMEVAL_T = "LL";
-
- $done = $start = pack($TIMEVAL_T, ());
-
- syscall( &SYS_gettimeofday, $start, 0)) != -1
- or die "gettimeofday: $!";
-
- ##########################
- # DO YOUR OPERATION HERE #
- ##########################
-
- syscall( &SYS_gettimeofday, $done, 0) != -1
- or die "gettimeofday: $!";
-
- @start = unpack($TIMEVAL_T, $start);
- @done = unpack($TIMEVAL_T, $done);
-
- # fix microseconds
- for ($done[1], $start[1]) { $_ /= 1_000_000 }
-
- $delta_time = sprintf "%.4f", ($done[0] + $done[1] )
- -
- ($start[0] + $start[1] );
-
-
- HHHHoooowwww ccccaaaannnn IIII ddddoooo aaaannnn _a_t_e_x_i_t() or _s_e_t_j_m_p()/_l_o_n_g_j_m_p()? (Exception
- handling)
-
- Release 5 of Perl added the END block, which can be used to
-
-
-
- Page 10 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- simulate _a_t_e_x_i_t(). Each package's END block is called when
- the program or thread ends (see the _p_e_r_l_m_o_d manpage manpage
- for more details).
-
- For example, you can use this to make sure your filter
- program managed to finish its output without filling up the
- disk:
-
- END {
- close(STDOUT) || die "stdout close failed: $!";
- }
-
- The END block isn't called when untrapped signals kill the
- program, though, so if you use END blocks you should also
- use
-
- use sigtrap qw(die normal-signals);
-
- Perl's exception-handling mechanism is its _e_v_a_l() operator.
- You can use _e_v_a_l() as setjmp and _d_i_e() as longjmp. For
- details of this, see the section on signals, especially the
- time-out handler for a blocking _f_l_o_c_k() in the section on
- _S_i_g_n_a_l_s in the _p_e_r_l_i_p_c manpage and chapter 6 of the Camel.
-
- If exception handling is all you're interested in, try the
- exceptions.pl library (part of the standard perl
- distribution).
-
- If you want the _a_t_e_x_i_t() syntax (and an _r_m_e_x_i_t() as well),
- try the AtExit module available from CPAN.
-
- WWWWhhhhyyyy ddddooooeeeessssnnnn''''tttt mmmmyyyy ssssoooocccckkkkeeeettttssss pppprrrrooooggggrrrraaaammmm wwwwoooorrrrkkkk uuuunnnnddddeeeerrrr SSSSyyyysssstttteeeemmmm VVVV
- ((((SSSSoooollllaaaarrrriiiissss))))???? WWWWhhhhaaaatttt ddddooooeeeessss tttthhhheeee eeeerrrrrrrroooorrrr mmmmeeeessssssssaaaaggggeeee """"PPPPrrrroooottttooooccccoooollll nnnnooootttt
- ssssuuuuppppppppoooorrrrtttteeeedddd"""" mmmmeeeeaaaannnn????
-
- Some Sys-V based systems, notably Solaris 2.X, redefined
- some of the standard socket constants. Since these were
- constant across all architectures, they were often hardwired
- into perl code. The proper way to deal with this is to "use
- Socket" to get the correct values.
-
- Note that even though SunOS and Solaris are binary
- compatible, these values are different. Go figure.
-
- HHHHoooowwww ccccaaaannnn IIII ccccaaaallllllll mmmmyyyy ssssyyyysssstttteeeemmmm''''ssss uuuunnnniiiiqqqquuuueeee CCCC ffffuuuunnnnccccttttiiiioooonnnnssss ffffrrrroooommmm PPPPeeeerrrrllll????
-
- In most cases, you write an external module to do it - see
- the answer to "Where can I learn about linking C with Perl?
- [h2xs, xsubpp]". However, if the function is a system call,
- and your system supports _s_y_s_c_a_l_l(), you can use the syscall
- function (documented in the _p_e_r_l_f_u_n_c manpage).
-
-
-
-
- Page 11 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- Remember to check the modules that came with your
- distribution, and CPAN as well - someone may already have
- written a module to do it.
-
- WWWWhhhheeeerrrreeee ddddoooo IIII ggggeeeetttt tttthhhheeee iiiinnnncccclllluuuuddddeeee ffffiiiilllleeeessss ttttoooo ddddoooo _i_o_c_t_l() or _s_y_s_c_a_l_l()?
-
- Historically, these would be generated by the h2ph tool,
- part of the standard perl distribution. This program
- converts _c_p_p(1) directives in C header files to files
- containing subroutine definitions, like &SYS_getitimer,
- which you can use as arguments to your functions. It
- doesn't work perfectly, but it usually gets most of the job
- done. Simple files like _e_r_r_n_o._h, _s_y_s_c_a_l_l._h, and _s_o_c_k_e_t._h
- were fine, but the hard ones like _i_o_c_t_l._h nearly always need
- to hand-edited. Here's how to install the *.ph files:
-
- 1. become super-user
- 2. cd /usr/include
- 3. h2ph *.h */*.h
-
- If your system supports dynamic loading, for reasons of
- portability and sanity you probably ought to use h2xs (also
- part of the standard perl distribution). This tool converts
- C header files to Perl extensions. See the _p_e_r_l_x_s_t_u_t
- manpage for how to get started with h2xs.
-
- If your system doesn't support dynamic loading, you still
- probably ought to use h2xs. See the _p_e_r_l_x_s_t_u_t manpage and
- the _E_x_t_U_t_i_l_s::_M_a_k_e_M_a_k_e_r manpage for more information (in
- brief, just use mmmmaaaakkkkeeee ppppeeeerrrrllll instead of a plain mmmmaaaakkkkeeee to rebuild
- perl with a new static extension).
-
- WWWWhhhhyyyy ddddoooo sssseeeettttuuuuiiiidddd ppppeeeerrrrllll ssssccccrrrriiiippppttttssss ccccoooommmmppppllllaaaaiiiinnnn aaaabbbboooouuuutttt kkkkeeeerrrrnnnneeeellll pppprrrroooobbbblllleeeemmmmssss????
-
- Some operating systems have bugs in the kernel that make
- setuid scripts inherently insecure. Perl gives you a number
- of options (described in the _p_e_r_l_s_e_c manpage) to work around
- such systems.
-
- HHHHoooowwww ccccaaaannnn IIII ooooppppeeeennnn aaaa ppppiiiippppeeee bbbbooootttthhhh ttttoooo aaaannnndddd ffffrrrroooommmm aaaa ccccoooommmmmmmmaaaannnndddd????
-
- The IPC::Open2 module (part of the standard perl
- distribution) is an easy-to-use approach that internally
- uses _p_i_p_e(), _f_o_r_k(), and _e_x_e_c() to do the job. Make sure
- you read the deadlock warnings in its documentation, though
- (see the _I_P_C::_O_p_e_n_2 manpage). See the section on
- _B_i_d_i_r_e_c_t_i_o_n_a_l _C_o_m_m_u_n_i_c_a_t_i_o_n _w_i_t_h _A_n_o_t_h_e_r _P_r_o_c_e_s_s in the
- _p_e_r_l_i_p_c manpage and the section on _B_i_d_i_r_e_c_t_i_o_n_a_l
- _C_o_m_m_u_n_i_c_a_t_i_o_n _w_i_t_h _Y_o_u_r_s_e_l_f in the _p_e_r_l_i_p_c manpage
-
- You may also use the IPC::Open3 module (part of the standard
- perl distribution), but be warned that it has a different
-
-
-
- Page 12 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- order of arguments from IPC::Open2 (see the _I_P_C::_O_p_e_n_3
- manpage).
-
- WWWWhhhhyyyy ccccaaaannnn''''tttt IIII ggggeeeetttt tttthhhheeee oooouuuuttttppppuuuutttt ooooffff aaaa ccccoooommmmmmmmaaaannnndddd wwwwiiiitttthhhh _s_y_s_t_e_m()?
-
- You're confusing the purpose of _s_y_s_t_e_m() and backticks (``).
- _s_y_s_t_e_m() runs a command and returns exit status information
- (as a 16 bit value: the low 7 bits are the signal the
- process died from, if any, and the high 8 bits are the
- actual exit value). Backticks (``) run a command and return
- what it sent to STDOUT.
-
- $exit_status = system("mail-users");
- $output_string = `ls`;
-
-
- HHHHoooowwww ccccaaaannnn IIII ccccaaaappppttttuuuurrrreeee SSSSTTTTDDDDEEEERRRRRRRR ffffrrrroooommmm aaaannnn eeeexxxxtttteeeerrrrnnnnaaaallll ccccoooommmmmmmmaaaannnndddd????
-
- There are three basic ways of running external commands:
-
- system $cmd; # using system()
- $output = `$cmd`; # using backticks (``)
- open (PIPE, "cmd |"); # using open()
-
- With _s_y_s_t_e_m(), both STDOUT and STDERR will go the same place
- as the script's versions of these, unless the command
- redirects them. Backticks and _o_p_e_n() read oooonnnnllllyyyy the STDOUT
- of your command.
-
- With any of these, you can change file descriptors before
- the call:
-
- open(STDOUT, ">logfile");
- system("ls");
-
- or you can use Bourne shell file-descriptor redirection:
-
- $output = `$cmd 2>some_file`;
- open (PIPE, "cmd 2>some_file |");
-
- You can also use file-descriptor redirection to make STDERR
- a duplicate of STDOUT:
-
- $output = `$cmd 2>&1`;
- open (PIPE, "cmd 2>&1 |");
-
- Note that you _c_a_n_n_o_t simply open STDERR to be a dup of
- STDOUT in your Perl program and avoid calling the shell to
- do the redirection. This doesn't work:
-
- open(STDERR, ">&STDOUT");
- $alloutput = `cmd args`; # stderr still escapes
-
-
-
- Page 13 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- This fails because the _o_p_e_n() makes STDERR go to where
- STDOUT was going at the time of the _o_p_e_n(). The backticks
- then make STDOUT go to a string, but don't change STDERR
- (which still goes to the old STDOUT).
-
- Note that you _m_u_s_t use Bourne shell (_s_h(1)) redirection
- syntax in backticks, not _c_s_h(1)! Details on why Perl's
- _s_y_s_t_e_m() and backtick and pipe opens all use the Bourne
- shell are in
- http://www.perl.com/CPAN/doc/FMTEYEWTK/versus/csh.whynot .
- To capture a command's STDERR and STDOUT together:
-
- $output = `cmd 2>&1`; # either with backticks
- $pid = open(PH, "cmd 2>&1 |"); # or with an open pipe
- while (<PH>) { } # plus a read
-
- To capture a command's STDOUT but discard its STDERR:
-
- $output = `cmd 2>/dev/null`; # either with backticks
- $pid = open(PH, "cmd 2>/dev/null |"); # or with an open pipe
- while (<PH>) { } # plus a read
-
- To capture a command's STDERR but discard its STDOUT:
-
- $output = `cmd 2>&1 1>/dev/null`; # either with backticks
- $pid = open(PH, "cmd 2>&1 1>/dev/null |"); # or with an open pipe
- while (<PH>) { } # plus a read
-
- To exchange a command's STDOUT and STDERR in order to
- capture the STDERR but leave its STDOUT to come out our old
- STDERR:
-
- $output = `cmd 3>&1 1>&2 2>&3 3>&-`; # either with backticks
- $pid = open(PH, "cmd 3>&1 1>&2 2>&3 3>&-|");# or with an open pipe
- while (<PH>) { } # plus a read
-
- To read both a command's STDOUT and its STDERR separately,
- it's easiest and safest to redirect them separately to
- files, and then read from those files when the program is
- done:
-
- system("program args 1>/tmp/program.stdout 2>/tmp/program.stderr");
-
- Ordering is important in all these examples. That's because
- the shell processes file descriptor redirections in strictly
- left to right order.
-
- system("prog args 1>tmpfile 2>&1");
- system("prog args 2>&1 1>tmpfile");
-
- The first command sends both standard out and standard error
- to the temporary file. The second command sends only the
-
-
-
- Page 14 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- old standard output there, and the old standard error shows
- up on the old standard out.
-
- WWWWhhhhyyyy ddddooooeeeessssnnnn''''tttt _o_p_e_n() return an error when a pipe open fails?
-
- It does, but probably not how you expect it to. On systems
- that follow the standard _f_o_r_k()/_e_x_e_c() paradigm (such as
- Unix), it works like this: _o_p_e_n() causes a _f_o_r_k(). In the
- parent, _o_p_e_n() returns with the process ID of the child.
- The child _e_x_e_c()s the command to be piped to/from. The
- parent can't know whether the _e_x_e_c() was successful or not -
- all it can return is whether the _f_o_r_k() succeeded or not.
- To find out if the command succeeded, you have to catch
- SIGCHLD and _w_a_i_t() to get the exit status. You should also
- catch SIGPIPE if you're writing to the child -- you may not
- have found out the _e_x_e_c() failed by the time you write.
- This is documented in the _p_e_r_l_i_p_c manpage.
-
- On systems that follow the _s_p_a_w_n() paradigm, _o_p_e_n() _m_i_g_h_t do
- what you expect - unless perl uses a shell to start your
- command. In this case the _f_o_r_k()/_e_x_e_c() description still
- applies.
-
- WWWWhhhhaaaatttt''''ssss wwwwrrrroooonnnngggg wwwwiiiitttthhhh uuuussssiiiinnnngggg bbbbaaaacccckkkkttttiiiicccckkkkssss iiiinnnn aaaa vvvvooooiiiidddd ccccoooonnnntttteeeexxxxtttt????
-
- Strictly speaking, nothing. Stylistically speaking, it's
- not a good way to write maintainable code because backticks
- have a (potentially humungous) return value, and you're
- ignoring it. It's may also not be very efficient, because
- you have to read in all the lines of output, allocate memory
- for them, and then throw it away. Too often people are
- lulled to writing:
-
- `cp file file.bak`;
-
- And now they think "Hey, I'll just always use backticks to
- run programs." Bad idea: backticks are for capturing a
- program's output; the _s_y_s_t_e_m() function is for running
- programs.
-
- Consider this line:
-
- `cat /etc/termcap`;
-
- You haven't assigned the output anywhere, so it just wastes
- memory (for a little while). Plus you forgot to check $? to
- see whether the program even ran correctly. Even if you
- wrote
-
- print `cat /etc/termcap`;
-
- In most cases, this could and probably should be written as
-
-
-
- Page 15 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- system("cat /etc/termcap") == 0
- or die "cat program failed!";
-
- Which will get the output quickly (as its generated, instead
- of only at the end) and also check the return value.
-
- _s_y_s_t_e_m() also provides direct control over whether shell
- wildcard processing may take place, whereas backticks do
- not.
-
- HHHHoooowwww ccccaaaannnn IIII ccccaaaallllllll bbbbaaaacccckkkkttttiiiicccckkkkssss wwwwiiiitttthhhhoooouuuutttt sssshhhheeeellllllll pppprrrroooocccceeeessssssssiiiinnnngggg????
-
- This is a bit tricky. Instead of writing
-
- @ok = `grep @opts '$search_string' @filenames`;
-
- You have to do this:
-
- my @ok = ();
- if (open(GREP, "-|")) {
- while (<GREP>) {
- chomp;
- push(@ok, $_);
- }
- close GREP;
- } else {
- exec 'grep', @opts, $search_string, @filenames;
- }
-
- Just as with _s_y_s_t_e_m(), no shell escapes happen when you
- _e_x_e_c() a list.
-
- There are more examples of this the section on _S_a_f_e _P_i_p_e
- _O_p_e_n_s in the _p_e_r_l_i_p_c manpage.
-
- WWWWhhhhyyyy ccccaaaannnn''''tttt mmmmyyyy ssssccccrrrriiiipppptttt rrrreeeeaaaadddd ffffrrrroooommmm SSSSTTTTDDDDIIIINNNN aaaafffftttteeeerrrr IIII ggggaaaavvvveeee iiiitttt EEEEOOOOFFFF ((((^^^^DDDD
- oooonnnn UUUUnnnniiiixxxx,,,, ^^^^ZZZZ oooonnnn MMMMSSSS----DDDDOOOOSSSS))))????
-
- Because some stdio's set error and eof flags that need
- clearing. The POSIX module defines _c_l_e_a_r_e_r_r() that you can
- use. That is the technically correct way to do it. Here
- are some less reliable workarounds:
-
- 1 Try keeping around the seekpointer and go there, like
- this:
-
- $where = tell(LOG);
- seek(LOG, $where, 0);
-
-
- 2 If that doesn't work, try seeking to a different part of
- the file and then back.
-
-
-
- Page 16 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- 3 If that doesn't work, try seeking to a different part of
- the file, reading something, and then seeking back.
-
- 4 If that doesn't work, give up on your stdio package and
- use sysread.
-
- HHHHoooowwww ccccaaaannnn IIII ccccoooonnnnvvvveeeerrrrtttt mmmmyyyy sssshhhheeeellllllll ssssccccrrrriiiipppptttt ttttoooo ppppeeeerrrrllll????
-
- Learn Perl and rewrite it. Seriously, there's no simple
- converter. Things that are awkward to do in the shell are
- easy to do in Perl, and this very awkwardness is what would
- make a shell->perl converter nigh-on impossible to write.
- By rewriting it, you'll think about what you're really
- trying to do, and hopefully will escape the shell's pipeline
- datastream paradigm, which while convenient for some
- matters, causes many inefficiencies.
-
- CCCCaaaannnn IIII uuuusssseeee ppppeeeerrrrllll ttttoooo rrrruuuunnnn aaaa tttteeeellllnnnneeeetttt oooorrrr ffffttttpppp sssseeeessssssssiiiioooonnnn????
-
- Try the Net::FTP, TCP::Client, and Net::Telnet modules
- (available from CPAN).
- http://www.perl.com/CPAN/scripts/netstuff/telnet.emul.shar
- will also help for emulating the telnet protocol, but
- Net::Telnet is quite probably easier to use..
-
- If all you want to do is pretend to be telnet but don't need
- the initial telnet handshaking, then the standard dual-
- process approach will suffice:
-
- use IO::Socket; # new in 5.004
- $handle = IO::Socket::INET->new('www.perl.com:80')
- || die "can't connect to port 80 on www.perl.com: $!";
- $handle->autoflush(1);
- if (fork()) { # XXX: undef means failure
- select($handle);
- print while <STDIN>; # everything from stdin to socket
- } else {
- print while <$handle>; # everything from socket to stdout
- }
- close $handle;
- exit;
-
-
- HHHHoooowwww ccccaaaannnn IIII wwwwrrrriiiitttteeee eeeexxxxppppeeeecccctttt iiiinnnn PPPPeeeerrrrllll????
-
- Once upon a time, there was a library called chat2.pl (part
- of the standard perl distribution), which never really got
- finished. If you find it somewhere, _d_o_n'_t _u_s_e _i_t. These
- days, your best bet is to look at the Expect module
- available from CPAN, which also requires two other modules
- from CPAN, IO::Pty and IO::Stty.
-
-
-
-
- Page 17 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- IIIIssss tttthhhheeeerrrreeee aaaa wwwwaaaayyyy ttttoooo hhhhiiiiddddeeee ppppeeeerrrrllll''''ssss ccccoooommmmmmmmaaaannnndddd lllliiiinnnneeee ffffrrrroooommmm pppprrrrooooggggrrrraaaammmmssss
- ssssuuuucccchhhh aaaassss """"ppppssss""""????
-
- First of all note that if you're doing this for security
- reasons (to avoid people seeing passwords, for example) then
- you should rewrite your program so that critical information
- is never given as an argument. Hiding the arguments won't
- make your program completely secure.
-
- To actually alter the visible command line, you can assign
- to the variable $0 as documented in the _p_e_r_l_v_a_r manpage.
- This won't work on all operating systems, though. Daemon
- programs like sendmail place their state there, as in:
-
- $0 = "orcus [accepting connections]";
-
-
- IIII {{{{cccchhhhaaaannnnggggeeeedddd ddddiiiirrrreeeeccccttttoooorrrryyyy,,,, mmmmooooddddiiiiffffiiiieeeedddd mmmmyyyy eeeennnnvvvviiiirrrroooonnnnmmmmeeeennnntttt}}}} iiiinnnn aaaa ppppeeeerrrrllll
- ssssccccrrrriiiipppptttt.... HHHHoooowwww ccccoooommmmeeee tttthhhheeee cccchhhhaaaannnnggggeeee ddddiiiissssaaaappppppppeeeeaaaarrrreeeedddd wwwwhhhheeeennnn IIII eeeexxxxiiiitttteeeedddd tttthhhheeee
- ssssccccrrrriiiipppptttt???? HHHHoooowwww ddddoooo IIII ggggeeeetttt mmmmyyyy cccchhhhaaaannnnggggeeeessss ttttoooo bbbbeeee vvvviiiissssiiiibbbblllleeee????
-
- Unix
- In the strictest sense, it can't be done -- the script
- executes as a different process from the shell it was
- started from. Changes to a process are not reflected in
- its parent, only in its own children created after the
- change. There is shell magic that may allow you to fake
- it by _e_v_a_l()ing the script's output in your shell; check
- out the comp.unix.questions FAQ for details.
-
- HHHHoooowwww ddddoooo IIII cccclllloooosssseeee aaaa pppprrrroooocccceeeessssssss''''ssss ffffiiiilllleeeehhhhaaaannnnddddlllleeee wwwwiiiitttthhhhoooouuuutttt wwwwaaaaiiiittttiiiinnnngggg ffffoooorrrr iiiitttt
- ttttoooo ccccoooommmmpppplllleeeetttteeee????
-
- Assuming your system supports such things, just send an
- appropriate signal to the process (see the section on _k_i_l_l
- in the _p_e_r_l_f_u_n_c manpage. It's common to first send a TERM
- signal, wait a little bit, and then send a KILL signal to
- finish it off.
-
- HHHHoooowwww ddddoooo IIII ffffoooorrrrkkkk aaaa ddddaaaaeeeemmmmoooonnnn pppprrrroooocccceeeessssssss????
-
- If by daemon process you mean one that's detached
- (disassociated from its tty), then the following process is
- reported to work on most Unixish systems. Non-Unix users
- should check their Your_OS::Process module for other
- solutions.
-
- +o Open /dev/tty and use the the TIOCNOTTY ioctl on it.
- See the _t_t_y(_4) manpage for details. Or better yet, you
- can just use the _P_O_S_I_X::_s_e_t_s_i_d() function, so you don't
- have to worry about process groups.
-
-
-
-
- Page 18 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- +o Change directory to /
-
- +o Reopen STDIN, STDOUT, and STDERR so they're not
- connected to the old tty.
-
- +o Background yourself like this:
-
- fork && exit;
-
-
- HHHHoooowwww ddddoooo IIII mmmmaaaakkkkeeee mmmmyyyy pppprrrrooooggggrrrraaaammmm rrrruuuunnnn wwwwiiiitttthhhh sssshhhh aaaannnndddd ccccsssshhhh????
-
- See the _e_g/_n_i_h script (part of the perl source
- distribution).
-
- HHHHoooowwww ddddoooo IIII ffffiiiinnnndddd oooouuuutttt iiiiffff IIII''''mmmm rrrruuuunnnnnnnniiiinnnngggg iiiinnnntttteeeerrrraaaaccccttttiiiivvvveeeellllyyyy oooorrrr nnnnooootttt????
-
- Good question. Sometimes -t STDIN and -t STDOUT can give
- clues, sometimes not.
-
- if (-t STDIN && -t STDOUT) {
- print "Now what? ";
- }
-
- On POSIX systems, you can test whether your own process
- group matches the current process group of your controlling
- terminal as follows:
-
- use POSIX qw/getpgrp tcgetpgrp/;
- open(TTY, "/dev/tty") or die $!;
- $tpgrp = tcgetpgrp(TTY);
- $pgrp = getpgrp();
- if ($tpgrp == $pgrp) {
- print "foreground\n";
- } else {
- print "background\n";
- }
-
-
- HHHHoooowwww ddddoooo IIII ttttiiiimmmmeeeeoooouuuutttt aaaa sssslllloooowwww eeeevvvveeeennnntttt????
-
- Use the _a_l_a_r_m() function, probably in conjunction with a
- signal handler, as documented the section on _S_i_g_n_a_l_s in the
- _p_e_r_l_i_p_c manpage and chapter 6 of the Camel. You may instead
- use the more flexible Sys::AlarmCall module available from
- CPAN.
-
- HHHHoooowwww ddddoooo IIII sssseeeetttt CCCCPPPPUUUU lllliiiimmmmiiiittttssss????
-
- Use the BSD::Resource module from CPAN.
-
-
-
-
-
- Page 19 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- HHHHoooowwww ddddoooo IIII aaaavvvvooooiiiidddd zzzzoooommmmbbbbiiiieeeessss oooonnnn aaaa UUUUnnnniiiixxxx ssssyyyysssstttteeeemmmm????
-
- Use the reaper code from the section on _S_i_g_n_a_l_s in the
- _p_e_r_l_i_p_c manpage to call _w_a_i_t() when a SIGCHLD is received,
- or else use the double-fork technique described in the fork
- entry in the _p_e_r_l_f_u_n_c manpage.
-
- HHHHoooowwww ddddoooo IIII uuuusssseeee aaaannnn SSSSQQQQLLLL ddddaaaattttaaaabbbbaaaasssseeee????
-
- There are a number of excellent interfaces to SQL databases.
- See the DBD::* modules available from
- http://www.perl.com/CPAN/modules/dbperl/DBD . A lot of
- information on this can be found at
- http://www.hermetica.com/technologia/perl/DBI/index.html .
-
- HHHHoooowwww ddddoooo IIII mmmmaaaakkkkeeee aaaa _s_y_s_t_e_m() exit on control-C?
-
- You can't. You need to imitate the _s_y_s_t_e_m() call (see the
- _p_e_r_l_i_p_c manpage for sample code) and then have a signal
- handler for the INT signal that passes the signal on to the
- subprocess. Or you can check for it:
-
- $rc = system($cmd);
- if ($rc & 127) { die "signal death" }
-
-
- HHHHoooowwww ddddoooo IIII ooooppppeeeennnn aaaa ffffiiiilllleeee wwwwiiiitttthhhhoooouuuutttt bbbblllloooocccckkkkiiiinnnngggg????
-
- If you're lucky enough to be using a system that supports
- non-blocking reads (most Unixish systems do), you need only
- to use the O_NDELAY or O_NONBLOCK flag from the Fcntl module
- in conjunction with _s_y_s_o_p_e_n():
-
- use Fcntl;
- sysopen(FH, "/tmp/somefile", O_WRONLY|O_NDELAY|O_CREAT, 0644)
- or die "can't open /tmp/somefile: $!":
-
-
- HHHHoooowwww ddddoooo IIII iiiinnnnssssttttaaaallllllll aaaa CCCCPPPPAAAANNNN mmmmoooodddduuuulllleeee????
-
- The easiest way is to have the CPAN module do it for you.
- This module comes with perl version 5.004 and later. To
- manually install the CPAN module, or any well-behaved CPAN
- module for that matter, follow these steps:
-
- 1 Unpack the source into a temporary area.
-
- 2
-
- perl Makefile.PL
-
-
-
-
-
- Page 20 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- 3
-
- make
-
-
- 4
-
- make test
-
-
- 5
-
- make install
-
-
- If your version of perl is compiled without dynamic loading,
- then you just need to replace step 3 (mmmmaaaakkkkeeee) with mmmmaaaakkkkeeee ppppeeeerrrrllll
- and you will get a new _p_e_r_l binary with your extension
- linked in.
-
- See the _E_x_t_U_t_i_l_s::_M_a_k_e_M_a_k_e_r manpage for more details on
- building extensions. See also the next question.
-
- WWWWhhhhaaaatttt''''ssss tttthhhheeee ddddiiiiffffffffeeeerrrreeeennnncccceeee bbbbeeeettttwwwweeeeeeeennnn rrrreeeeqqqquuuuiiiirrrreeee aaaannnndddd uuuusssseeee????
-
- Perl offers several different ways to include code from one
- file into another. Here are the deltas between the various
- inclusion constructs:
-
- 1) do $file is like eval `cat $file`, except the former:
- 1.1: searches @INC and updates %INC.
- 1.2: bequeaths an *unrelated* lexical scope on the eval'ed code.
-
- 2) require $file is like do $file, except the former:
- 2.1: checks for redundant loading, skipping already loaded files.
- 2.2: raises an exception on failure to find, compile, or execute $file.
-
- 3) require Module is like require "Module.pm", except the former:
- 3.1: translates each "::" into your system's directory separator.
- 3.2: primes the parser to disambiguate class Module as an indirect object.
-
- 4) use Module is like require Module, except the former:
- 4.1: loads the module at compile time, not run-time.
- 4.2: imports symbols and semantics from that package to the current one.
-
- In general, you usually want use and a proper Perl module.
-
- HHHHoooowwww ddddoooo IIII kkkkeeeeeeeepppp mmmmyyyy oooowwwwnnnn mmmmoooodddduuuulllleeee////lllliiiibbbbrrrraaaarrrryyyy ddddiiiirrrreeeeccccttttoooorrrryyyy????
-
- When you build modules, use the PREFIX option when
- generating Makefiles:
-
-
-
-
- Page 21 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- perl Makefile.PL PREFIX=/u/mydir/perl
-
- then either set the PERL5LIB environment variable before you
- run scripts that use the modules/libraries (see the _p_e_r_l_r_u_n
- manpage) or say
-
- use lib '/u/mydir/perl';
-
- See Perl's the _l_i_b manpage for more information.
-
- HHHHoooowwww ddddoooo IIII aaaadddddddd tttthhhheeee ddddiiiirrrreeeeccccttttoooorrrryyyy mmmmyyyy pppprrrrooooggggrrrraaaammmm lllliiiivvvveeeessss iiiinnnn ttttoooo tttthhhheeee
- mmmmoooodddduuuulllleeee////lllliiiibbbbrrrraaaarrrryyyy sssseeeeaaaarrrrcccchhhh ppppaaaatttthhhh????
-
- use FindBin;
- use lib "$FindBin::Bin";
- use your_own_modules;
-
-
- HHHHoooowwww ddddoooo IIII aaaadddddddd aaaa ddddiiiirrrreeeeccccttttoooorrrryyyy ttttoooo mmmmyyyy iiiinnnncccclllluuuuddddeeee ppppaaaatttthhhh aaaatttt rrrruuuunnnnttttiiiimmmmeeee????
-
- Here are the suggested ways of modifying your include path:
-
- the PERLLIB environment variable
- the PERL5LIB environment variable
- the perl -Idir commpand line flag
- the use lib pragma, as in
- use lib "$ENV{HOME}/myown_perllib";
-
- The latter is particularly useful because it knows about
- machine dependent architectures. The lib.pm pragmatic
- module was first included with the 5.002 release of Perl.
-
- AAAAUUUUTTTTHHHHOOOORRRR AAAANNNNDDDD CCCCOOOOPPPPYYYYRRRRIIIIGGGGHHHHTTTT
- Copyright (c) 1997, 1998 Tom Christiansen and Nathan
- Torkington. All rights reserved.
-
- When included as part of the Standard Version of Perl, or as
- part of its complete documentation whether printed or
- otherwise, this work may be distributed only under the terms
- of Perl's Artistic License. Any distribution of this file
- or derivatives thereof _o_u_t_s_i_d_e of that package require that
- special arrangements be made with copyright holder.
-
- Irrespective of its distribution, all code examples in this
- file are hereby placed into the public domain. You are
- permitted and encouraged to use this code in your own
- programs for fun or for profit as you see fit. A simple
- comment in the code giving credit would be courteous but is
- not required.
-
-
-
-
-
-
- Page 22 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 23 (printed 10/23/98)
-
-
-
-
-
-
-